Skip to content

config: add entry-point-based plugin schema discovery#10994

Open
adamlabadorf wants to merge 5 commits intotreeverse:mainfrom
adamlabadorf:feature/plugin-schema-discovery
Open

config: add entry-point-based plugin schema discovery#10994
adamlabadorf wants to merge 5 commits intotreeverse:mainfrom
adamlabadorf:feature/plugin-schema-discovery

Conversation

@adamlabadorf
Copy link

Closes #10993

Summary

Adds _discover_plugin_schemas() to dvc/config_schema.py, which iterates over installed dvc.fs entry points at import time and merges any REMOTE_CONFIG class attributes into REMOTE_SCHEMAS. This lets third-party filesystem plugins register their own URL schemes and config keys without modifying DVC core.

Changes

  • dvc/config_schema.py — adds _discover_plugin_schemas() (~25 lines) called once at module load
  • tests/unit/test_plugin_schema_discovery.py — 7 new unit tests

Behavior

Plugin declares its config schema:

class OSFFileSystem(ObjectFileSystem):
    protocol = "osf"
    REMOTE_CONFIG: ClassVar[dict] = {
        "token": str,
        "project_id": str,
        "provider": str,
        "endpoint_url": str,
    }

DVC discovers it automatically when the plugin is installed — no changes to DVC core needed per-plugin.

Properties

  • ✅ Backward compatible — hardcoded schemes (s3, gs, etc.) are never overwritten
  • ✅ Zero overhead without third-party plugins
  • ✅ Graceful — plugins that fail to load are silently skipped
  • ✅ Handles single and tuple protocol values
  • ✅ 22/22 relevant unit tests passing (test_plugin_schema_discovery + test_config)
  • ✅ ruff clean

Motivation

Developed alongside dvc-osf, a plugin for Open Science Framework storage. Without this change, dvc remote add myremote osf://... raises Unsupported URL type osf:// before the filesystem ever loads. With it, all DVC remote operations work correctly (30 integration tests passing against a real OSF project).

Allow DVC filesystem plugins to declare a REMOTE_CONFIG class attribute
on their filesystem class. At import time, _discover_plugin_schemas()
iterates over installed dvc.fs entry points and merges any declared
config schemas into REMOTE_SCHEMAS, enabling ByUrl to accept custom
URL schemes without changes to DVC core.

This makes DVC truly extensible for third-party storage backends
(e.g. OSF, GitLab packages) that define their own URL schemes.

Existing hardcoded schemes are never overwritten.

Relates to treeverse#9711.
@github-project-automation github-project-automation bot moved this to Backlog in DVC Feb 20, 2026
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@adamlabadorf adamlabadorf force-pushed the feature/plugin-schema-discovery branch from 1029b4f to 81944fe Compare February 20, 2026 21:41
Allow DVC filesystem plugins to declare a REMOTE_CONFIG class attribute
on their filesystem class. At import time, _discover_plugin_schemas()
iterates over installed dvc.fs entry points and merges any declared
config schemas into REMOTE_SCHEMAS, enabling ByUrl to accept custom
URL schemes without changes to DVC core.

This makes DVC truly extensible for third-party storage backends
(e.g. OSF, GitLab packages) that define their own URL schemes.

Existing hardcoded schemes are never overwritten.

Fixes treeverse#10993
@adamlabadorf adamlabadorf force-pushed the feature/plugin-schema-discovery branch from 81944fe to e244e12 Compare February 20, 2026 21:41
@codecov
Copy link

codecov bot commented Feb 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.00%. Comparing base (2431ec6) to head (161efd5).
⚠️ Report is 192 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #10994      +/-   ##
==========================================
+ Coverage   90.68%   91.00%   +0.32%     
==========================================
  Files         504      506       +2     
  Lines       39795    41213    +1418     
  Branches     3141     3263     +122     
==========================================
+ Hits        36087    37506    +1419     
- Misses       3042     3069      +27     
+ Partials      666      638      -28     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

entry_points(group=...) keyword argument was added in Python 3.10.
On Python 3.9, use the dict-based entry_points().get(group, []) API instead.

Fixes TypeError on Python 3.9:
  TypeError: entry_points() got an unexpected keyword argument 'group'
Extract entry point fetching into _get_dvc_fs_entry_points() helper so
that tests can mock it directly rather than mocking entry_points().
This avoids the Python 3.9 vs 3.10+ dict/list API difference leaking
into test mocks.
mypy evaluates sys.version_info >= (3, 10) as always True on 3.10+
environments, flagging the 3.9 fallback return as unreachable.
Extend the type: ignore comment to cover both call-arg and unreachable.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

config: allow filesystem plugins to declare their own remote config schema via entry points

2 participants